package org.dromara.solonplugins.j2cache;

import java.io.IOException;
import java.util.Properties;

import org.noear.solon.core.AopContext;
import org.noear.solon.core.Plugin;
import org.noear.solon.core.Props;

import net.oschina.j2cache.CacheChannel;
import net.oschina.j2cache.J2CacheBuilder;
import net.oschina.j2cache.J2CacheConfig;

/**
 * Solon插件入口
 *
 * @author: aoshiguchen
 */
public class XPluginImp implements Plugin {
    @Override
    public void start(AopContext context) throws Throwable {
        Props conf = context.cfg();
        CacheChannel cc = getCacheChannel(conf);
        context.wrapAndPut(CacheChannel.class, cc);
    }


    private CacheChannel getCacheChannel(Props conf) throws IOException {
    	String PRE = "j2cache.";
        Properties broadcastProperties = new Properties();
        Properties l1CacheProperties = new Properties();
        Properties l2CacheProperties = new Properties();

        
        String serialization= trim(conf.get(PRE+"serialization"));//序列化类型,可以有:fst(fast-serialization),kyro(kyro),java(java standard)
        String broadcast = trim(conf.get(PRE+"broadcast"));//广播类型,例如redis
        String l1CacheName = trim(conf.get(PRE+"L1.provider_class"));//L1缓存提供者,可以有:none,ehcache,ehcache3,caffeine,redis
        String l2CacheName = trim(conf.get(PRE+"L2.provider_class"));//L2缓存提供者,可以有:none,ehcache,ehcache3,caffeine,redis

        String PROP_REDIS_SYNCTTLTOREDIS= PRE + "redis.syncTtlToRedis";//Redis的syncTtlToRedis,控制缓存有效期,可以有:true(同步一级缓存ttl),false(永不过期)
        String syncTtlToRedis = trim(conf.get(PROP_REDIS_SYNCTTLTOREDIS,"true"));
        
        conf.forEach((key,val)->{
        	String k = (String)key;
        	if(k.startsWith(PRE+broadcast + ".")) {
                broadcastProperties.setProperty(k.substring(PRE.length()+((broadcast + ".").length())), (String)val);
            }
            else if(k.startsWith(PRE+l1CacheName + ".")) {
                l1CacheProperties.setProperty(k.substring(PRE.length()+((l1CacheName + ".").length())),(String)val);
            }
            //也许 l2CacheName==broadcast=="redis"
            if(k.startsWith(PRE+l2CacheName + ".")) {
                l2CacheProperties.setProperty(k.substring(PRE.length()+((l2CacheName + ".").length())), (String)val);
            }
        });

        J2CacheConfig j2CacheConfig = new J2CacheConfig();
        j2CacheConfig.setBroadcast(broadcast);
        j2CacheConfig.setBroadcastProperties(broadcastProperties);
        j2CacheConfig.setL1CacheName(l1CacheName);
        j2CacheConfig.setL1CacheProperties(l1CacheProperties);
        j2CacheConfig.setSerialization(serialization);
        j2CacheConfig.setL2CacheName(l2CacheName);
        j2CacheConfig.setL2CacheProperties(l2CacheProperties);
        j2CacheConfig.setSyncTtlToRedis(Boolean.parseBoolean(syncTtlToRedis));

        return J2CacheBuilder.init(j2CacheConfig).getChannel();
    }
    
    /**
     * 去掉字符串前后空白字符。空白字符的定义由Character.isWhitespace来判断
     *
     * @param cs
     *            字符串
     * @return 去掉了前后空白字符的新字符串
     */
    private String trim(CharSequence cs) {
        if (null == cs)
            return null;
        int length = cs.length();
        if (length == 0)
            return cs.toString();
        int l = 0;
        int last = length - 1;
        int r = last;
        for (; l < length; l++) {
            if (!Character.isWhitespace(cs.charAt(l)))
                break;
        }
        for (; r > l; r--) {
            if (!Character.isWhitespace(cs.charAt(r)))
                break;
        }
        if (l > r)
            return "";
        else if (l == 0 && r == last)
            return cs.toString();
        return cs.subSequence(l, r + 1).toString();
    }
}
